<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-08-01 15:52:57
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 管道漫游
-->
<!--相机基础-->
<template>
	<div id="three_container"></div>
</template>

<script setup>
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import TWEEN from "@tweenjs/tween.js"; //1. tweenjs创建threejs动画
let container = null;
const scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(200);
scene.add(axesHelper);
onMounted(() => {
	container = document.querySelector("#three_container");
	const camera = new THREE.PerspectiveCamera(
		90,
		container.offsetWidth / container.offsetHeight,
		0.1,
		1000
	);
	camera.position.z = 200;
	camera.lookAt(0, 0, 0);
	//-
	const renderer = new THREE.WebGLRenderer({
		antialias: true
	});
	renderer.shadowMap.enabled = true;
	renderer.setSize(container.offsetWidth, container.offsetHeight);
	container.appendChild(renderer.domElement);

	const controls = new OrbitControls(camera, renderer.domElement);
	controls.update();
	render();
	function render() {
		TWEEN.update();
		renderer.render(scene, camera);
		requestAnimationFrame(render);
	}

	// Demo();
	Demo1();
	// Demo2();
	Demo3();
});
function Demo() {
	const geometry = new THREE.PlaneGeometry(50, 50);
	const material = new THREE.MeshBasicMaterial({
		color: 0xffff00
	});
	const mesh = new THREE.Mesh(geometry, material);
	// scene.add(mesh);
	console.log("顶点位置数据", geometry.attributes.position);
	const vertexShader = `
  void main() {
    gl_PointSize = 20.0;
    // // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
    // // 注意矩阵乘法前后顺序不要写错
    // gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position,1.0 );
    // modelViewMatrix，就是视图矩阵viewMatrix和模型矩阵modelMatrix的乘积。
    //你可以把上面代码viewMatrix*modelMatrix简化为modelViewMatrix。
    gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4( position, 1.0 );
  }
  `;

	// 片元着色器代码
	const fragmentShader = `
void main() {
    // RGB 0.0,1.0,1.0对应16进制颜色是0x00ffff
    gl_FragColor = vec4(1.0,1.0,1.0,0.5);
}
`;
	const shaderMaterial = new THREE.ShaderMaterial({
		vertexShader, //顶点着色器
		fragmentShader, // 片元着色器
		transparent: true, //允许透明
		side: THREE.DoubleSide //双面显示
	});
	const mesh1 = new THREE.Mesh(geometry, shaderMaterial);
	scene.add(mesh1);
	mesh1.position.x = 100;
}

function Demo1() {
	const fragmentShader = `
    uniform float opacity;
    uniform vec3 color;//声明一个颜色变量color

    void main() {
      gl_FragColor = vec4(color,opacity);
    }
  `;
	const geometry = new THREE.PlaneGeometry(30, 30);
	const material = new THREE.ShaderMaterial({
		uniforms: {
			opacity: { value: 0.5 }, // 给透明度uniform变量opacity传值
			color: { value: new THREE.Color(0x00ffff) }
		},
		transparent: true,
		side: THREE.DoubleSide,
		fragmentShader
	});
	const mesh = new THREE.Mesh(geometry, material);
	scene.add(mesh);
	mesh.position.y = 100;
	// let tween = new TWEEN.Tween({ index: 0 })
	// 	.to({ index: 100 }, 1000)
	// 	.onUpdate(function (t) {
	// 		console.log(t.index / 100, "t");
	// 		material.uniforms.opacity.value = t.index / 100;
	// 	})
	// 	.repeat(Infinity);
	// tween.start();
}
const createCatmullRomCurve3 = (start, end, depth) => {
	// p1、p3轨迹线起始点坐标
	const p1 = new THREE.Vector3(...start);
	const p3 = new THREE.Vector3(...end);
	// 计算p1和p3的中点坐标
	const x2 = (p1.x + p3.x) / 2;
	const y2 = (p1.y + p3.y) / 2;
	const z2 = (p1.z + p3.z) / 2;
	function depthHandler(value) {
		if (value !== "undefined" || value !== "null") {
			return value;
		} else {
			return false;
		}
	}
	const p2 = new THREE.Vector3(
		depthHandler(depth.x) || x2,
		depthHandler(depth.y) || y2,
		depthHandler(depth.z) || z2
	);
	const arr = [p1, p2, p3];
	// 三维样条曲线
	return new THREE.CatmullRomCurve3(arr);
};
function Demo2() {
	const fragmentShader = `
    uniform float opacity;
    uniform vec3 color;//声明一个颜色变量color

    void main() {
      // 根据片元的x坐标，来设置片元的像素值
if(gl_FragCoord.x < float(${container.offsetWidth / 2})){
  gl_FragColor = vec4(1.0,0.0,0.0,opacity);
}else {
discard;//不符合条件片元直接舍弃掉
  // gl_FragColor = vec4(0.6,1.0,1.0,1.0);
}
// // 片元沿着x方向渐变
//  gl_FragColor = vec4(gl_FragCoord.x/800.0*1.0,0.0,0.0,1.0);
    }
  `;
	const geometry = new THREE.PlaneGeometry(30, 30);
	const material = new THREE.ShaderMaterial({
		uniforms: {
			opacity: { value: 1.0 }, // 给透明度uniform变量opacity传值
			color: { value: new THREE.Color(0x00ffff) }
		},
		transparent: true,
		side: THREE.DoubleSide,
		fragmentShader
	});
	const mesh = new THREE.Mesh(geometry, material);
	scene.add(mesh);
}
function Demo3() {
	const path = createCatmullRomCurve3([-10, 0, -10], [10, 0, 10], { y: 20 });
	const geometry = new THREE.BufferGeometry();
	const points = path.getPoints(200);
	geometry.setFromPoints(points);
	const vertexShader = `
    void main() {
      gl_PointSize = 20.0;
      gl_Position = projectionMatrix*viewMatrix*modelMatrix*vec4( position, 1.0 );
    }
  `;
	const fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0,1.0,1.0,1.0);
    }
  `;
	// material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
	const material = new THREE.ShaderMaterial({
		// uniforms: {
		// 	opacity: { value: 1 }, // 给透明度uniform变量opacity传值
		// 	color: { value: new THREE.Color(0x00ffff) }
		// },
		transparent: true,
		side: THREE.DoubleSide,
		vertexShader,
		fragmentShader
	});
	const mesh = new THREE.Points(geometry, material);
	scene.add(mesh);
	mesh.position.y = 100;
}
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
.downLoadBtn {
	position: absolute;
	right: 0;
	top: 10px;
	z-index: 99;
}
</style>
